/*
Package seed
@Author   : Uyynot
@Email    : uyynot@qq.com
@Time     : 2024/4/25 18:13
@File     : seeder.go
@Project  : gohub
@Desc     :
*/
package seed

import (
	"gohub/pkg/console"
	"gohub/pkg/database"
	"gorm.io/gorm"
)

type SeederFunc func(*gorm.DB)

// 对应每一个database/seeders目录下的Seeder文件
type Seeder struct {
	Func SeederFunc
	Name string
}

// 存放所有Seeder
var seeders []Seeder

// 按顺序执行的 Seeder 数组
// 支持一些必须按顺序执行的 seeder，例如 topic 创建的
// 时必须依赖于 user, 所以 TopicSeeder 应该在 UserSeeder 后执行
var orderedSeederNames []string

// Add 注册到seeders数组中
func Add(name string, fn SeederFunc) {
	seeders = append(seeders, Seeder{
		Name: name,
		Func: fn,
	})
}

// SetRunOrder
// @Description: 设置 桉树需执行的Seeder数组
// @param names
func SetRunOrder(names []string) {
	orderedSeederNames = names
}

// GetSeeder
// @Description: 通过名称来获取Seeder对象
// @param name
// @return Seeder
func GetSeeder(name string) Seeder {
	for _, sdr := range seeders {
		if name == sdr.Name {
			return sdr
		}
	}
	return Seeder{}
}

// RunAll
// @Description: 执行所有Seeder
func RunAll() {
	//先运行ordered的
	executed := make(map[string]string)

	for _, name := range orderedSeederNames {
		sdr := GetSeeder(name)
		if len(sdr.Name) > 0 {
			console.Warning("Running OrderedSeeder: " + sdr.Name)
			sdr.Func(database.DB)
			executed[name] = name
		}
	}

	//在运行剩下的
	for _, sdr := range seeders {
		//过滤已运行的
		if _, ok := executed[sdr.Name]; !ok {
			console.Warning("Running Seeder: " + sdr.Name)
			sdr.Func(database.DB)
		}
	}
}

// RunSeeder
// @Description: 运行打个Seeder
// @param name
func RunSeeder(name string) {
	for _, sdr := range seeders {
		if name == sdr.Name {
			sdr.Func(database.DB)
			break
		}
	}
}
